import json
import sys, os, clr
from multiprocessing import Condition
import importlib
import yaml
from game_engine_process import GameEngineProcess
from agent_process import AgentProcess
from scheduler import Scheduler


def create_instance_from_file(file_path, class_name='Agent'):
    spec = importlib.util.spec_from_file_location(class_name, file_path)
    module = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(module)
    return getattr(module, class_name)()


if __name__ == "__main__":
    # 读取配置文件
    config_path = os.getcwd() + "\\..\\config\\"
    with open(config_path+"config.yml", "r", encoding="utf-8") as file:
        config = yaml.safe_load(file)

    # 通过sys导入智能体所在目录
    agent_dir = config['agent_dir']
    sys.path.append(agent_dir)

    # 读取想定文件
    scenario_path = config_path + config['Scenario']
    with open(scenario_path, "r", encoding="utf-8") as file:
        scenario = json.load(file)

    # --- 导入兵棋引擎 ---
    # === 导入Wargame_V3_0的动态链接库DLL ===
    sys.path.append(os.getcwd()) #+ "\\master\\")
    clr.FindAssembly("Wargame_V3_1.dll")
    wargame_dll = clr.AddReference("Wargame_V3_1")  # 必须把dll文件拷贝到py文件同一个目录中，否则加载不了程序集
    from Wargame_V3_1 import GameEnvolver
    
    game_envolver = GameEnvolver(config_path)  # 导入兵棋引擎
    # --- End ---

    # --- 导入Agent引擎 ---
    red_ai = create_instance_from_file(agent_dir+"\\"+config['agents']['Red'])
    blue_ai = create_instance_from_file(agent_dir+"\\"+config['agents']['Blue'])
    red_ai.setup(scenario, color="Red")  # setup函数读取配置文件的内容，完成初始化
    blue_ai.setup(scenario, color="Blue")
    # --- End ---

    # --- 配置接口信息 ---
    ip = config['ip']
    first_port = config['ports']
    authkey = config['authkey'].encode('utf-8')
    agent_colors = config['agent_colors']

    scheduler = Scheduler(agent_colors, ip, first_port, authkey)
    game_engine = GameEngineProcess((ip, first_port), authkey, game_envolver.step) 
    agent_red = AgentProcess((ip, first_port+1), authkey, red_ai.step)  # TODO 传入实例化的agent.step()方法，区分agent_red和agent_blue
    agent_blue = AgentProcess((ip, first_port+2), authkey, blue_ai.step)
    agent_red.start()
    agent_blue.start()
    game_engine.start()
    scheduler.start()
